/*
 * @Author: zhangshu
 * @email: shiliang.zhang@tuya.com
 * @LastEditors: Please set LastEditors
 * @file name: app_mfg.c
 * @Description: 
 * @Copyright: HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD
 * @Company: http://www.tuya.com
 * @Date: 2022-02-08
 * @LastEditTime: 2022-02-08
 */
#include "tal_mf_test.h"
#include "tal_memory.h"
#include "tal_adc.h"

#include "app_common.h"
#include "app_mfg.h"
#include "app_led.h"
#include "app_gpio.h"
#include "tal_sw_timer.h"
#include "tkl_network_manager.h"

TIMER_ID mf_delay_send_event_id;

STATIC VOID_T dev_mf_battery_send(VOID_T);

extern VOID_T __tuya_key_init(VOID_T);
extern VOID_T __tuya_led_init(VOID_T);
extern VOID_T __tuya_gpio_init(VOID_T);
extern VOID_T __tuya_battery_init(VOID_T);

// mf_test sensor type enum
typedef enum {
    DOOR_SENSOR = 0,    // door sensor:0x00
    PIR_SENSOR,         // pir motion sensor:0x01
    PHOTO_SENSOR,       // photo sensor:0x02
    SMOKE_SENSOR,       // smoke sensor:0x03
    GAS_SENSOR,         // gas sensor:0x04
    WATER_SENSOR,       // water sensor:0x05
    CO_SENSOR,          // CO sensor:0x06
    SOS_SENSOR          // SOS sensor:0x07
}OEM_SENSOR_TYPE_E;

//mfg test flag
STATIC UINT8_T mfg_test = MFG_TEST_NONE;
BOOL_T  mf_test_doing_flag = FALSE;
BOOL_T  sys_init_finish_flag = FALSE;

extern UINT16_T tl_bdbInstallCodeCRC16(UINT8_T *pInstallCode, UINT8_T len);

/**
 * @description: manufactor test handler callback
 * @param[in] cmd: manufacture command, refer to TUYA_MF_TEST_CMD_T
 * @param[in] arg: callback data
 * @param[in] arg_len: data length
 * @return: TUYA_MF_TEST_RET_T, success when TUYA_MF_TEST_SUCCESS, or else
 */
TUYA_MF_TEST_RET_T tal_mf_test_handle_callback(TUYA_MF_TEST_CMD_T cmd,
                                                          UINT8_T*arg, 
                                                          UINT16_T arg_len)
{
    USER_PR_DEBUG("mf test cmd %x, arg0[%x],arg_len[%d]!!!\r\n", cmd, arg[0],arg_len);
    for(UINT16_T i = 0; i < arg_len; i++){
        USER_PR_DEBUG("%x ", arg[i]);
    }
    USER_PR_DEBUG("\r\n");

    switch(cmd)
    {
        case(TUYA_MF_TEST_LED_ON_ALL):
        {
            __tuya_led_init();
            mf_test_blink(TUYA_MF_TEST_LED_ON_ALL);
            break;
        }
        case(TUYA_MF_TEST_LED_OFF_ALL):
        {
            __tuya_led_init();
            mf_test_blink(TUYA_MF_TEST_LED_OFF_ALL);
            break;
        }
        case(TUYA_MF_TEST_LED_BLINK_ALL):
        {
            __tuya_led_init();
            mfg_test = MFG_TEST_LED;
            mf_test_blink(TUYA_MF_TEST_LED_BLINK_ALL);
            break;
        }
        case(TUYA_MF_TEST_RELAY_ON_ALL):
        {
            break;
        }
        case(TUYA_MF_TEST_RELAY_OFF_ALL):
        {
            break;
        }
        case(TUYA_MF_TEST_RELAY_BLINK_ALL):
        {
            break;
        }
        case(TUYA_MF_TEST_BUTTON):
        {
            USER_PR_DEBUG("mf test key !!!\r\n");
            __tuya_gpio_init();
            app_gpio_preheat_init();
            mf_test_blink(TUYA_MF_TEST_LED_OFF_ALL);
            mfg_test = MFG_TEST_NET_KEY;
            return TUYA_MF_TEST_DOING;
        }
        case(TUYA_MF_TRANSFER):
        {
            switch (arg[0])
            {
                // enter test
                case 0x00: {  
                    USER_PR_DEBUG("enter mf test !!!\r\n");
                    mf_test_blink(TUYA_MF_TEST_LED_OFF_ALL);
                    mfg_test = MFG_TEST_START;
                    mf_test_doing_flag = TRUE;
                    tkl_cpu_force_wakeup();
                    tuya_zg_poll_duration_set(30*1000);
                  break;
                }
                case 0x0B: {  
                    USER_PR_DEBUG("mf_test sensor !!!\r\n");
                    __tuya_gpio_init();
                    app_gpio_preheat_init();
                    // sensor test
                    if (arg[1] == DOOR_SENSOR || arg[1] == PIR_SENSOR ||
                        arg[1] == SMOKE_SENSOR || arg[1] == GAS_SENSOR ||
                        arg[1] == WATER_SENSOR || arg[1] == CO_SENSOR) {
                        USER_PR_DEBUG("start alarm test\r\n");
                        mfg_test = MFG_TEST_ALARM;
                        return TUYA_MF_TEST_DOING;
                    }
                    //tamper test
                    if (0x07 == arg[1])  {
                        USER_PR_DEBUG("statr tamper test\r\n");
                        mfg_test = MFG_TEST_TAMPER;
                        return TUYA_MF_TEST_DOING;
                    }
                    break;
                }
                //light color test
                case 0x13: {
                    mfg_test = MFG_TEST_LIGHT_COLOR;
                    //tuya_sensor_set_sample(SENSOR_SAMPLE_TYPE_LIGHT_COLOR);
                    return TUYA_MF_TEST_DOING;
                }
                case 0x90: {
                    mfg_test = MFG_TEST_BATTERY;
                    __tuya_battery_init();
                    tal_sw_timer_start(mf_delay_send_event_id, 200, TAL_TIMER_ONCE);
                    return TUYA_MF_TEST_DOING;//todo
                }
                default:
                    break;
            }
        }
        default:
            break;
    }


    return TUYA_MF_TEST_SUCCESS;
}

/**
 * @description: key mfg test callback
 * @param[in] key_id: key id
 * @return: TRUE when test success or else
*/
BOOL_T mfg_key_test_callback(UINT32_T key_id)
{
    if (mfg_test != MFG_TEST_NET_KEY) {
        USER_PR_DEBUG("not net key mfg test\r\n");
        return FALSE;
    }
    mf_test_blink(TUYA_MF_TEST_LED_OFF_ALL);
    tal_mf_test_button_test_notify(key_id);
    return TRUE;
}

/**
 * @description: alarm1 mfg test callback
 * @param [in] {g_state} alarm gpio status
 * @return: TRUE when test success or else
 */
BOOL_T mfg_alarm1_test_callback(UINT8_T g_state)
{
    if (mfg_test != MFG_TEST_ALARM) {
        //USER_PR_DEBUG("not alarm mfg test\r\n");
        return FALSE;
    }
    if(g_state) {
        tal_mf_test_bool_sensor_notify(PIR_SENSOR, 0, TRUE);
    } else {
        tal_mf_test_bool_sensor_notify(PIR_SENSOR, 0, FALSE);
    }
    return TRUE;
}

/**
 * @description: tamper mfg test callback
 * @param [in] {g_state} tamper gpio status
 * @return: TRUE when test success or else
 */
BOOL_T mfg_tamper_test_callback(UINT8_T g_state)
{
    if (mfg_test != MFG_TEST_TAMPER) {
        USER_PR_DEBUG("not tamper mfg test\r\n");
        return FALSE;
    }
    if (g_state) {
        tal_mf_test_bool_sensor_notify(0x07, 0x00, TRUE);
    } else {
        tal_mf_test_bool_sensor_notify(0x07, 0x00, FALSE);
    }
    return TRUE;
}

/**
 * @description: trouble mfg test callback
 * @param [in] {g_state} trouble gpio status
 * @return: TRUE when test success or else
 */
BOOL_T mfg_trouble_test_callback(UINT8_T g_state)
{
    if (mfg_test != MFG_TEST_TAMPER) {
        USER_PR_DEBUG("not trouble mfg test\r\n");
        return FALSE;
    }
    if (g_state) {
        tal_mf_test_bool_sensor_notify(0x07, 0x00, TRUE);
    } else {
        tal_mf_test_bool_sensor_notify(0x07, 0x00, FALSE);
    }
    return TRUE;
}

/**
 * @description: dev_mf_battery_send
 * @param {type} none
 * @return: none
 */
STATIC VOID_T dev_mf_battery_send(VOID_T)
{
    UINT8_T report[] = {'{', '"', 'P', '"', ':', '1', ',', '"',
                        'B', '"', ':', '0', '0', '0', '0', '}'};

    INT32_T adc_raw_val = 0;
    tal_adc_read_single_channel(TUYA_ADC_NUM_0, 1, &adc_raw_val);

    for (UINT8_T i = 0; i < 4; i++) {
      report[14 - i] = adc_raw_val % 10 + '0';
      adc_raw_val = adc_raw_val / 10;
    }
    tal_mf_test_general_send(0x90, sizeof(report), report);
}

VOID_T __mf_delay_send_event(TIMER_ID timer_id, VOID_T *arg)
{
    dev_mf_battery_send();
}

/**
* @description: clear mfg flag
* @param[in] none
* @return: none
*/
VOID_T clear_mfg_test_flag(VOID_T)
{
    mfg_test = MFG_TEST_NONE;
}

/**
 * @description: get mfg test flag
 * @param[in] none
 * @return: none
*/
UINT8_T get_mfg_test(VOID_T)
{
  return mfg_test;
}

